#ifndef MESHSLICE_MESHSCISSOR_H
#define MESHSLICE_MESHSCISSOR_H

#include "meshtypes.h"
#include <OgreSceneManager.h>

namespace MeshSlice {

    using namespace Ogre;

    class MeshScissor
    {
    public:
        /**
         * @brief Constructs new mesh slicer
         * @param pSceneMgr Pointer to Scene Manager
         * @param scissorPlaneVertices Array of four vertices of the scissor plane in world coordinates
         */
        MeshScissor(
                SceneManager *pSceneMgr,
                Vector3 scissorPlaneVertices[4]);

        /// Sets new scissor plane's world coordinates
        void setScissorPlane(Vector3 scissorPlaneVertices[4]);

        /**
         * @brief Main function
         * @param meshPtr Mesh to split
         * @param sceneNode Scene node of the mesh. It needs to obtain world position of the mesh
         * @param pOutUpperMeshBlockList Upper part
         * @param pOutLowerMeshBlockList Lower part
         */
        void DoSplit(
                MeshPtr meshPtr,
                const Vector3 &position,
                const Quaternion &orientation,
                const Vector3 &scale,
                QList<SubMeshBlock> &pOutUpperMeshBlockList,
                QList<SubMeshBlock> &pOutLowerMeshBlockList);

        /// Returns new manual object after split
        ManualObject *makeObject(const QList<SubMeshBlock> &meshBlockList, const String &materialName);

    private:
        SceneManager    *mpSceneMgr;
        Vector3         *mPlaneVertices; // SliceFace Vertex Info

        void GetMeshInformation(
                MeshPtr mesh,
                unsigned int &vertex_count,
                Vector3 *vertices,
                Vector2 *texvertices,
                unsigned int &index_count,
                quint64 *indices,
                const Vector3 &position,
                const Quaternion &orientation,
                const Vector3 &scale);

        void GetMeshInformation(
                MeshPtr mesh,
                const Vector3 &position,
                const Quaternion &orientation,
                const Vector3 &scale,
                QList<SubMeshBlock> &pOutSubMeshBlock);

        bool fuzzyContains(const QList<Vector3> &list, const Vector3 &item, const Real &tolerance);

        void CalculateSplitFaceVertex(QList<Vector3> &vIntersectPosVerticesList, QList<Vector3> &vIntersectNormalVerticesList,
                SubMeshBlock &pUpperSplitFaceBlock,
                SubMeshBlock &pLowerSplitFaceBlock);

        bool CheckIntersectPointPolygonBetweenLine(Vector3 vTempPlanePoint[],
                const Vector3 &vA,
                const Vector3 &vB,
                const Vector2 &vTexA,
                const Vector2 &vTexB, const Vector3 &vNormA, const Vector3 &vNormB,
                Vector3 &vABIntersectPoint, Vector3 &vABIntersectNormal,
                Vector2 &vABTexVertex);
    };

} // namespace MeshSlice

#endif // MESHSLICE_MESHSCISSOR_H
